package logger

import (
	"strings"
	"time"
)

// LoggerAppender
type LoggerAppender struct {
	name       string
	level      Level
	additivity bool
	appenders  []*Appender
}

var appenders = make(map[string]*Appender)

var loggerAppenders = make(map[string]*LoggerAppender)

var rootAppender *LoggerAppender

type StringWriterImpl struct {
	loggerAppender *LoggerAppender
}

func (w *StringWriterImpl) WriteString(time time.Time, name, level, text string) (n int, err error) {
	n = 0
	err = nil
	for _, appender := range w.loggerAppender.appenders {
		n, err = (*appender).Output().WriteString(time, name, level, text)
	}
	return n, err
}

func NewLogger(name string) Logger {
	return NewDefaultLogger(name, func(l *DefaultLogger) {
		// 设置日志级别
		b := false
		l.output = []StringWriter{}
		for _, appender := range loggerAppenders {
			if strings.HasPrefix(name, appender.name) {
				l.SetLevel(appender.level)
				l.output = append(l.output, &StringWriterImpl{loggerAppender: appender})
				b = true
				if !appender.additivity {
					break
				}
			}
		}
		if b {
			return
		}
		if rootAppender != nil {
			l.SetLevel(rootAppender.level)
			l.output = append(l.output, &StringWriterImpl{loggerAppender: rootAppender})
		}
	})
}

func AddAppender(appender Appender) {
	if appender.Name() == "" {
		return
	}
	appenders[appender.Name()] = &appender
}

func AddLoggerAppender(name, level string, additivity bool, strAppender ...string) {
	loggerAppender := &LoggerAppender{
		name:       name,
		level:      parseLevel(level),
		additivity: additivity,
		appenders:  make([]*Appender, 0),
	}
	for _, appenderName := range strAppender {
		appender, exists := appenders[appenderName]
		if exists {
			loggerAppender.appenders = append(loggerAppender.appenders, appender)
		}
	}
	if len(loggerAppender.appenders) == 0 {
		return
	}
	loggerAppenders[name] = loggerAppender
}

func AddRootLoggerAppender(level string, strAppender ...string) {
	rootAppender = &LoggerAppender{
		name:       "ROOT",
		level:      parseLevel(level),
		additivity: false,
		appenders:  make([]*Appender, 0),
	}
	for _, appenderName := range strAppender {
		appender, exists := appenders[appenderName]
		if exists {
			rootAppender.appenders = append(rootAppender.appenders, appender)
		}
	}
}
